﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using planerka.Common;
using NLog;
using planerka.DataAccess.Models;
using planerka.Common.Enums;
using System.Configuration;
using System.Web.Security;
using System.Web.Mvc;

namespace planerka.DataAccess.DataService
{
    
    public class MessagesService
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();
       
        // отправить сообщение с просьбой активации аккаунта
        public void sendTemplatedEmail
            (List<SelectListItem> replaceItems, string toEmail, MessageTypes messageType)
        {
            
            PageService pageService = new PageService();
            _Repository<page> pageRepo = new _Repository<page>();
            page inviteEmailpage = pageService.getPage(messageType.ToString()); 
            if (inviteEmailpage != null)
            {
                string mailBody = inviteEmailpage.HTML_text;
                string mailSubject = inviteEmailpage.HTML_announce;

                foreach (var replaceItem in replaceItems)
                {
                    mailBody = mailBody.Replace(replaceItem.Text, replaceItem.Value);
                    mailSubject = mailSubject.Replace(replaceItem.Text, replaceItem.Value);
                }

                string fromMail = ConfigurationManager.AppSettings["smtpHostLogin"];
                
                try
                {
                    EmailSMTP_Service _emailService = new EmailSMTP_Service();
                    EmailSMTP_Service.RunToNextThread nextThread = _emailService.ExecuteHtmlSendMail;
                    //этот код будет выполнятся асинхронно и не будет останавливать основной поток
                    nextThread.BeginInvoke(
                        emailLoginTypes.service,
                        toEmail,
                        mailBody,
                        mailSubject,
                        null,
                        null, null,
                        _emailService.Callback,
                        nextThread);

                }
                catch (Exception ex)
                {
                    ExceptionUtility.LogException(logger, ex, "public void sendTemplatedEmail(...)",
                        "Ошибка отправки почты");

                }
            }
            else
            {
                ExceptionUtility.LogException(logger, new Exception(), "public void sendTemplatedEmail(...)",
                    "Не задана страница шаблона: " + messageType.ToString());
            }


        }

        // получить список сообщений по задаче
        public List<message> getMessagesForTask(long task_ID)
        {
            return new _Repository<message>().FindAll(p => p.task_ID == task_ID).ToList();
        }

        // получить список контрагентов, которым можно отправлять сообщения по задаче
        public List<user> getUsersForTask(long task_ID)
        {
            long owner_ID = 0;
            long? customer_ID = 0;
            long? performer_ID = 0;

            using (_Repository<task> taskRepo = new _Repository<task>())
            {
                task _task = taskRepo.FindAll(p => p.ID == task_ID).FirstOrDefault();
                if (_task == null)
                    return new List<user>();
                else 
                {
                    owner_ID = _task.project.owner_ID;
                    customer_ID = _task.project.customer_ID;
                    performer_ID = _task.performer_ID;
                }
            }

            List<user> users = new List<user>();
            UserService userService = new UserService();
            
            using (_Repository<user> userRepo = new _Repository<user>())
            {
                // Администратор
                //user currentUser = userService.getCurrentUser();
                user tmpUser = userRepo.FindAll(p => p.ID == owner_ID).FirstOrDefault();
                if (tmpUser != null && tmpUser.isEmailApproved)// && tmpUser.ID != currentUser.ID)
                {
                    tmpUser.projectRole = projectRoles.Administrator;
                    users.Add(tmpUser);
                } 

                // Заказчик
                tmpUser = userRepo.FindAll(p => p.ID == customer_ID).FirstOrDefault();
                if (tmpUser != null && tmpUser.isEmailApproved)// && tmpUser.ID != currentUser.ID)
                {
                    tmpUser.projectRole = projectRoles.Customer;
                    users.Add(tmpUser);
                }

                // Исполнитель
                tmpUser = userRepo.FindAll(p => p.ID == performer_ID).FirstOrDefault();
                if (tmpUser != null && tmpUser.isEmailApproved)// && tmpUser.ID != currentUser.ID)
                {
                    tmpUser.projectRole = projectRoles.Perfomer;
                    users.Add(tmpUser);
                }

               
            }

            return users;
        }

        // добавить сообщение к задаче
        public bool addMessage(long task_ID, string message, string taskName, long fromUser_ID, long toUser_ID, bool sendMail)
        {
            bool messageAddedSuccessfully = true;
            message addMessage = new message();
            addMessage.guid = Guid.NewGuid();
            addMessage.task_ID = task_ID;
            addMessage.text = message;
            addMessage.isRead = false;
            addMessage.timestamp = DateTime.Now;

            List<user> taskUsers = new MessagesService().getUsersForTask(task_ID);
            bool weCanSendMail = false;
            string fromMail = "";
            string toMail = "";
            string toName = "";

            using (_Repository<user> userRepo = new _Repository<user>())
            {

                user tmpUser = userRepo.FindAll(p => p.ID == toUser_ID).FirstOrDefault();
                if (tmpUser != null)
                {
                    // кому
                    addMessage.to_userID = tmpUser.ID;
                    addMessage.toUserName = tmpUser.nameView;
                    addMessage.toUserRole = taskUsers.Where(p => p.ID == tmpUser.ID).First().projectRole.GetHashCode();

                    weCanSendMail = true; // продублировать сообщение на почту
                    toMail = tmpUser.email;
                    toName = tmpUser.nameView;
                }
                // от кого
                
                tmpUser = userRepo.FindAll(p => p.ID == fromUser_ID).FirstOrDefault();
                addMessage.from_userID = tmpUser.ID;
                addMessage.fromUserName = tmpUser.nameView;
                addMessage.fromUserRole = taskUsers.Where(p => p.ID == tmpUser.ID).First().projectRole.GetHashCode();

                fromMail = tmpUser.email;
            }

            long message_ID = 0;
            using (_Repository<message> messageRepo = new _Repository<message>())
            {
                messageRepo.InsertInstance(addMessage);
                try
                {
                    messageRepo.Save();
                    message_ID = addMessage.ID;
                }
                catch (Exception ex)
                {
                    weCanSendMail = false;
                    messageAddedSuccessfully = false;
                    ExceptionUtility.LogException(logger, ex,
                    "[HttpPost] public ActionResult taskDetails(task _task, FormCollection formValues, string confirmButton)",
                    "Ошибка сохранения сообщения _task.ID: " + task_ID);

                }
            }

            // sendMail - дали команду отправить почту
            // weCanSendMail - есть возможность произвести отправку 
            // т.е. почта корреспондента подтверждена и сообщение успешно добавлено
            if (sendMail && weCanSendMail)
            {
                // отправить сообщение email контрагенту
                string mailSubject = "Новое сообщение (Planerka.info): " + taskName;
                string mailBody = "Здравствуйте, " + toName + "!";
                mailBody += @"<br /> Вам отправлено новое сообщение. 
                                        Вы можете ответить на него либо ответив на сообщение email, <br />Либо вы можете это сделать в карточке задачи: ";

                string taskURL = "http://www.planerka.info/tm/taskDetails/" + task_ID;
                mailBody += @"<a href=""" + taskURL + @""">" + taskURL + "</a><hr />";

                mailBody += message;

                EmailSMTP_Service _emailService = new EmailSMTP_Service();
                EmailSMTP_Service.RunToNextThread nextThread = _emailService.ExecuteHtmlSendMail;
                //этот код будет выполнятся асинхронно и не будет останавливать основной поток
                nextThread.BeginInvoke(
                    emailLoginTypes.router,
                    toMail,
                    mailBody,
                    mailSubject,
                    null,
                    null,
                    addMessage.guid,
                    _emailService.Callback,
                    nextThread);
            }

            return messageAddedSuccessfully;
        }

        // обновить статус сообщения email
        public emailMessageStatuse updateEmailMessageStatus
            (string emailMessage_ID, 
            bool forwarded, 
            bool addedToTask,
            int forwardAttempts)
        {
            emailMessageStatuse _emailMessageStatuse;
            _Repository<emailMessageStatuse> emailMessageStatuseRepo = new _Repository<emailMessageStatuse>();

            _emailMessageStatuse = emailMessageStatuseRepo.FindAll(p => p.emailMessage_ID == emailMessage_ID).FirstOrDefault();
            if (_emailMessageStatuse == null)
            {
                // add
                _emailMessageStatuse = new emailMessageStatuse();
                _emailMessageStatuse.emailMessage_ID = emailMessage_ID;
                _emailMessageStatuse.forwarded = forwarded;
                _emailMessageStatuse.addedToTask = addedToTask;
                _emailMessageStatuse.forwardAttempts = forwardAttempts;

                emailMessageStatuseRepo.InsertInstance(_emailMessageStatuse);

            }
            else
            {
                // update
                _emailMessageStatuse.forwarded = forwarded;
                _emailMessageStatuse.addedToTask = addedToTask;
                _emailMessageStatuse.forwardAttempts = forwardAttempts;
            }

            // save
            try { emailMessageStatuseRepo.Save(); }
            catch (Exception ex) 
            {
                ExceptionUtility.LogException(logger, ex,
                    "public emailMessageStatuse updateEmailMessageStatus(string emailMessage_ID, bool forwarded, bool addedToTask))",
                    "Ошибка сохранения статуса почтового сообщения emailMessage_ID: " + emailMessage_ID);
            }

            return _emailMessageStatuse;
        }

        // получить статус сообщения email
        public emailMessageStatuse getEmailMessageStatus(string emailMessage_ID)
        {
           return new _Repository<emailMessageStatuse>().FindAll(p => p.emailMessage_ID == emailMessage_ID).FirstOrDefault();
        }
    }
}
